package com.liusu.spider;


import org.json.JSONException;
import org.json.JSONObject;

import java.io.*;
import java.net.Socket;

public class Plate {

    public static Socket socket;
    public static String host="192.168.100.121";
    public static int port=8131;
    public static int count=5;
    public static String carPlate="";

    public static void connect ( ) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    socket = new Socket(host, port);
                    configFormat( ENABLE_PUSH, JSON_FMT, DISABLE_IMAGE); // 配置的方式：主动推送，JSON格式，不带图片
                    keepAlive();
                    while (!socket.isClosed()) {
                        int packetLen = recvPacketSize(socket);
                        if (packetLen > 0) {
                            // 接收实际数据
                            byte[] data = new byte[packetLen];
                            int recvLen = recvBlock(data, packetLen);
                            if (recvLen > 0) {
                                onRecv(data, recvLen);
                            } else {
                                //Log.d("Plate","socket error");
                                System.out.println("socket error");
                            }
                        } else if (packetLen == 0) {
                            count=0;
                            //Log.d("Plate","recv a keep-alive packet!!!"); // 接收到心跳包
                            System.out.println("recv a keep-alive packet!!!");
                        } else {
                            //Log.d("Plate","msg fmt wrong!");  // error
                            System.out.println("msg fmt wrong!");
                        }
                        //Thread.sleep(1000);
                    }
                    socket.close();
                } catch (Exception e) {
                    //Log.d("Plate","Error:" + e);
                }
            }
        }).start();
    }

    public static void keepAlive() {
        new Thread(new Runnable() {
            public void run() {
                while(!socket.isClosed()) {
                    try {
                        sendKeepAlive();
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    //通过心跳 检查与PLC通信连接情况
    public static void check() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (true) {
                        if(count>4) {

                        }
                        //Log.d("PlateCount",String.valueOf(count));
                        count++;
                        Thread.sleep(1 * 1000);
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static void onRecv(byte[] data, int len) throws UnsupportedEncodingException {
        if (len > 20 * 1024) {
            // 带图片数据
            //onIVSResultRecv(data, len);
        } else {
            // 普通的指令响应
            /*JSONObject json= JSONUtil.parseObj(infomessage);
            Map plateResult=(Map)json.get("PlateResult");*/
            try {
                String infomessage = new String(data,"GBK");
                System.out.println(infomessage);
                JSONObject json=new JSONObject(infomessage);
                JSONObject plateResult=json.getJSONObject("PlateResult");
                if(plateResult!=null){
                    carPlate =plateResult.getString("license");
                    //Log.d("Plate","**********onLongClick***"+carPlate);
                    System.out.println("**********onLongClick***"+carPlate);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    public static void AddWhiteList(Socket socket) {
        String cmd = "{" + "\"cmd\":\"white_list_operator\"," + "\"operator_type\":\"update_or_add\","
                + "\"dldb_rec\":{" + "\"create_time\":\"2018-10-1 12:30:40\","
                + "\"enable_time\":\"2018-08-08 12:30:40\"," + "\"overdue_time\":\"2018-12-12 12:30:40\","
                + "\"enable\":1," + "\"plate\":\"川A12345\"," + "\"time_seg_enable\":0," + "\"seg_time\": \"\","
                + "\"need_alarm\":0," + "\"vehicle_code\":\"123456\"," + "\"vehicle_comment\":\"123456\","
                + "\"customer_id\":1" + "}" + "} ";
        try {
            byte[] b = cmd.getBytes("gb2312");// 编码
            String sa = new String(b, "gb2312");// 解码

            sendCmd(sa);
        } catch (Exception e) {
            System.out.println("Error:" + e);
        }

    }

    public static void parseBinIVSResult(byte[] data, int len) {
        int pos = 0;

        if (data[2] == BLOCK_TYPE_BIN_RESULT) {
            int blockSize = convBytesToInt(data, 4);
            // data 8开始blockSize为结构体数据
            // 图片数据
            pos = 8 + blockSize;
            if (data[pos] == 'I' && data[pos + 1] == 'R') {
                if (data[pos + 2] == BLOCK_TYPE_IMAGE_DATA) {
                    int imageSize = convBytesToInt(data, pos + 4);
                    // data pos+8开始imageSize具体的图片数据
                    // saveImage(data,pos,len);
                }
            }
        }
    }

    public static void onIVSResultRecv(byte[] data, int len) {
        // 接收到识别结果的处理
        if (data[0] == 'I' && data[1] == 'R') {
            // 二进制的结构体处理
            parseBinIVSResult(data, len);
        } else {
            // json处理
            int pos = 0;
            while (true) {
                if (data[pos] == 0) {
                    break;
                }
                pos++;
            }

            String ivs = new String(data, 0, pos);
            System.out.println(ivs);

            //

            // 此处改为通过json来解析车牌识别结果,来获取车牌图片的大小
            int nImgSize = len - pos - 1;

            // 获取图片的大小
            saveImage(data, pos + 1, nImgSize, "D:\\test__1.jpg");
        }
    }

    protected static void WriteTxt(String path, String txt) {
        try {
            FileWriter f = new FileWriter(path);
            BufferedWriter bw = new BufferedWriter(f);
            bw.write(txt);
            bw.close();
        } catch (Exception e) {
        }
    }

    public static boolean sendCmd(String cmd) {
        try {
            int len = cmd.getBytes().length;
            byte[] header = { 'V', 'Z', 0, 0, 0, 0, 0, 0 };
            header[4] += (byte) ((len >> 24) & 0xFF);
            header[5] += (byte) ((len >> 16) & 0xFF);
            header[6] += (byte) ((len >> 8) & 0xFF);
            header[7] += (byte) (len & 0xFF);

            OutputStream out = socket.getOutputStream();
            out.write(header);
            out.write(cmd.getBytes());
        } catch (Exception e) {
            System.out.println("Error:" + e.getMessage());
            return false;
        }
        return true;
    }

    public static boolean sendKeepAlive( ) {
        try {
            byte[] buff = { 'V', 'Z', 1, 0, 0, 0, 0, 0 };

            OutputStream out = socket.getOutputStream();
            out.write(buff);
        } catch (Exception e) {
            System.out.println("Error:" + e);
            return false;
        }
        return true;
    }

    public static boolean configFormat( int enable, int fmt, int image) {
        String cmd;
        cmd = String.format(
                "{" + "\"cmd\" : \"ivsresult\"," + "\"enable\" : %s," + "\"format\" : \"%s\"," + "\"image\" : %s" + "}",
                enable != 0 ? "true" : "false", fmt != 0 ? "json" : "bin", image != 0 ? "true" : "false");

        return sendCmd(cmd);
    }

    public static int convBytesToInt(byte[] buff, int offset) {
        // 4bytes 转为int，要考虑机器的大小端问题
        int len, byteValue;
        len = 0;
        byteValue = (0x000000FF & ((int) buff[offset]));
        len += byteValue << 24;
        byteValue = (0x000000FF & ((int) buff[offset + 1]));
        len += byteValue << 16;
        byteValue = (0x000000FF & ((int) buff[offset + 2]));
        len += byteValue << 8;
        byteValue = (0x000000FF & ((int) buff[offset + 3]));
        len += byteValue;
        return len;
    }

    public static int recvPacketSize(Socket socket) {
        byte[] header = new byte[8];
        int recvLen = recvBlock(header, 8);
        if (recvLen <= 0) {
            return -1;
        }

        if (header[0] != 'V' || header[1] != 'Z') {
            // 格式不对
            return -1;
        }

        if (header[2] == 1) {
            // 心跳包
            return 0;
        }

        return convBytesToInt(header, 4);
    }

    // 接收指定长度的数据，收完为止
    public static int recvBlock( byte[] buff, int len) {
        try {
            InputStream in = socket.getInputStream();
            int totleRecvLen = 0;
            int recvLen;
            while (totleRecvLen < len) {
                recvLen = in.read(buff, totleRecvLen, len - totleRecvLen);
                totleRecvLen += recvLen;
            }
            return len;
        } catch (Exception e) {
            System.out.println("recvBlock timeout!");
            System.out.println("Error:"+e);
            return -1;
        }
    }

    public static int saveImage(byte[] buff, int pos, int len, String imgPath) {
        int ret = -1;
        try {
            DataOutputStream out = new DataOutputStream(new FileOutputStream(imgPath));
            out.write(buff, pos, len);
            out.close();
        } catch (IOException io) {
            System.out.println("save image failed " + imgPath);
        }

        return ret;
    }

    public static final String getsnCmd = "{\"cmd\" :\"getsn\"}";
    public static final String triggerCmd = "{\"cmd\" :\"trigger\"}";
    public static final int DISABLE_PUSH = 0;
    public static final int ENABLE_PUSH = 1;
    public static final int JSON_FMT = 1;
    public static final int BIN_FMT = 0;
    public static final int DISABLE_IMAGE = 0;
    public static final int ENABLE_IMAGE = 1;
    public static final int BLOCK_TYPE_BIN_RESULT = 1;
    public static final int BLOCK_TYPE_IMAGE_DATA = 2;

}
